package cn.findviewbydream.evil.app.service.impl;

import cn.findviewbydream.evil.app.dao.MenuDAO;
import cn.findviewbydream.evil.app.dto.MealBean;
import cn.findviewbydream.evil.app.exception.InsertLinkOrderOrderItemException;
import cn.findviewbydream.evil.app.exception.InsertOrderException;
import cn.findviewbydream.evil.app.exception.InsertOrderItemException;
import cn.findviewbydream.evil.app.service.MenuService;
import cn.findviewbydream.evil.app.service.OrderService;
import cn.findviewbydream.evil.app.websocket.WebSocketHandlerImpl;
import cn.findviewbydream.evil.main.entity.BaseMealTypeEntity;
import cn.findviewbydream.evil.main.entity.MealEntity;
import cn.findviewbydream.evil.main.entity.OrderEntity;
import cn.findviewbydream.evil.main.entity.OrderItemEntity;
import cn.findviewbydream.evil.mealorderofwaiter.enums.SocketEventType;
import cn.findviewbydream.evil.motowaiter.dto.OrderBean;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/********************************************
 * 工程名：MealOrder
 * 包名：cn.findviewbydream.evil.app.service.impl
 * 时间：17-1-19
 * 作者：白雨濃 evil
 * 邮箱：evilbai@foxmail.com
 * 内容：由于Gson原因,不得不采用java
 ********************************************/
@Service
public class MenuServiceImpl implements MenuService
{
    private Logger logger = LoggerFactory.getLogger(MenuService.class);

    private final OrderService orderService;
    private final MenuDAO menuDAO;

    @Autowired
    public MenuServiceImpl(MenuDAO menuDAO, OrderService orderService)
    {
        this.menuDAO = menuDAO;
        this.orderService = orderService;
    }

    @Nullable
    @Override
    public List<MealBean> getMealList()
    {
        List<MealBean> beanList = new ArrayList<>();
        List<MealEntity> entityList = menuDAO.selectMealList();

        for (MealEntity entity : entityList)
        {
            //TODO:根据菜品排序

            /*时令菜品剔除*/
            if (entity.getMonthToMarket() != null)
                if (!entity.getMonthToMarket().equals(""))
                {
                    String[] to = entity.getMonthToMarket().split("-");
                    int start = Integer.valueOf(to[0]);
                    int end = Integer.valueOf(to[1]);
                    int now = LocalDate.now().getMonth().getValue();

                /*开始结算分为两种情况*/
                /*第一种:6-9 同年的类型*/
                    if (start < end)
                    {
                        if (now < start || now > end)
                            continue;
                    }
                /*第二种:9-3 跨年的类型*/
                    else
                    {
                        if (now < start && now > end)
                            continue;
                    }
                }

            beanList.add(new MealBean(entity));
        }
        return beanList;
    }

    @Nullable
    @Override
    public List<BaseMealTypeEntity> getBaseMealTypeList()
    {
        return menuDAO.selectBaseMealTypeList();
    }

    @Nullable
    @Override
    @Transactional
    public Boolean setOrder(@NotNull String json) throws RuntimeException
    {
        int count;
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        OrderBean orderBean = gson.fromJson(json, new TypeToken<OrderBean>() {}.getType());

        OrderEntity orderEntity = orderBean.getOrder();
        List<OrderItemEntity> orderItemEntityList = orderBean.getItemList();
        if (orderEntity != null && orderItemEntityList != null)
        {
            orderEntity.setCreateDateTime(new Date());
            int orderId = 0;

            try
            {
                count = menuDAO.insertOrder(orderEntity);
                orderId = orderEntity.getOrderId();
                if (count != 1)
                    throw new InsertOrderException("写入订单错误");
            }
            catch (Exception e)
            {
                logger.error(e.toString());
                throw new InsertOrderException("写入订单错误");
            }

            int orderItemId;
            for (OrderItemEntity entity : orderItemEntityList)
            {
                try
                {
                    count = menuDAO.insertOrderItem(entity);
                    if (count != 1)
                        throw new InsertOrderItemException("写入订单项目错误");
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                    throw new InsertOrderItemException("写入订单项目错误");
                }

                try
                {
                    orderItemId = entity.getOrderItemId();
                    count = menuDAO.insertLinkOrderOrderItem(orderId, orderItemId);
                    if (count != 1)
                        throw new InsertLinkOrderOrderItemException("写入订单与订单项目链接错误");
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                    throw new InsertLinkOrderOrderItemException("写入订单与订单项目链接错误");
                }
            }

            /*成功插入后->发送Socket 状态102 刷新订单列表*/
            WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.ORDERLIST.getIndex());
            /*成功插入后->发送Socket 状态101 刷新座位列表*/
            WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.SEATLIST.getIndex());
            return true;
        }
        return false;
    }


    @Nullable
    @Override
    @Transactional
    public Boolean setOrderUpdate(@NotNull String json) throws RuntimeException
    {
        int count;
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        OrderBean orderBean = gson.fromJson(json, new TypeToken<OrderBean>() {}.getType());

        OrderEntity orderEntity = orderBean.getOrder();
        List<OrderItemEntity> orderItemEntityList = orderBean.getItemList();
        if (orderEntity != null && orderItemEntityList != null)
        {
            orderEntity.setCreateDateTime(new Date());
            int orderId = 0;

            try
            {
                count = menuDAO.updateOrder(orderEntity);
                orderId = orderEntity.getOrderId();
                if (count != 1)
                    throw new InsertOrderException("写入订单错误");
            }
            catch (Exception e)
            {
                logger.error(e.toString());
                throw new InsertOrderException("写入订单错误");
            }

            int orderItemId;
            for (OrderItemEntity entity : orderItemEntityList)
            {
                try
                {
                    count = menuDAO.insertOrderItem(entity);
                    if (count != 1)
                        throw new InsertOrderItemException("写入订单项目错误");
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                    throw new InsertOrderItemException("写入订单项目错误");
                }

                try
                {
                    orderItemId = entity.getOrderItemId();
                    count = menuDAO.insertLinkOrderOrderItem(orderId, orderItemId);
                    if (count != 1)
                        throw new InsertLinkOrderOrderItemException("写入订单与订单项目链接错误");
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                    throw new InsertLinkOrderOrderItemException("写入订单与订单项目链接错误");
                }
            }
            /*结束后,更新总钱数*/
            orderService.setOrderTotalUpdate(orderId);

            /*成功插入后->发送Socket 状态102 刷新订单列表*/
            WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.ORDERLIST.getIndex());
            return true;
        }
        return false;
    }
}
